#pragma once
#include <algorithm>
#include <cstdint>
#include <string_view>

static constexpr uint8_t vga_font[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 32 space
    0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00, // 33 !
    0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, // 34 "
    0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, // 35 #
    0x18, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x18, 0x00, // 36 $
    0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00, // 37 %
    0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, // 38 &
    0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, // 39 '
    0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, // 40 (
    0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, // 41 )
    0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, // 42 *
    0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, // 43 +
    0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, // 44 ,
    0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, // 45 -
    0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, // 46 .
    0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, // 47 /
    0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00, // 48 0
    0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, // 49 1
    0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, // 50 2
    0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, // 51 3
    0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00, // 52 4
    0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, // 53 5
    0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, // 54 6
    0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, // 55 7
    0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, // 56 8
    0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, // 57 9
    0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, // 58 :
    0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, // 59 ;
    0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, // 60 <
    0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, // 61 =
    0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, // 62 >
    0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, // 63 ?
    0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00, // 64 @
    0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, // 65 A
    0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, // 66 B
    0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00, // 67 C
    0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, // 68 D
    0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, // 69 E
    0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00, // 70 F
    0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00, // 71 G
    0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, // 72 H
    0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, // 73 I
    0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, // 74 J
    0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, // 75 K
    0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, // 76 L
    0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, // 77 M
    0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, // 78 N
    0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, // 79 O
    0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, // 80 P
    0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00, // 81 Q
    0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00, // 82 R
    0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00, // 83 S
    0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, // 84 T
    0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, // 85 U
    0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, // 86 V
    0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00, // 87 W
    0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00, // 88 X
    0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, // 89 Y
    0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, // 90 Z
    0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, // 91 [
    0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, // 92 backslash
    0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, // 93 ]
    0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, // 94 ^
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, // 95 _
    0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // 96 `
    0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, // 97 a
    0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, // 98 b
    0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, // 99 c
    0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, // 100 d
    0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, // 101 e
    0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00, // 102 f
    0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, // 103 g
    0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, // 104 h
    0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, // 105 i
    0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, // 106 j
    0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, // 107 k
    0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, // 108 l
    0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xC6, 0x00, // 109 m
    0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, // 110 n
    0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, // 111 o
    0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, // 112 p
    0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, // 113 q
    0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00, // 114 r
    0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x00, // 115 s
    0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00, // 116 t
    0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, // 117 u
    0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, // 118 v
    0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00, // 119 w
    0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, // 120 x
    0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, // 121 y
    0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, // 122 z
    0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, // 123 {
    0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, // 124 |
    0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, // 125 }
    0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // 126 ~
};

inline void
render_text_to_image(std::string_view text, unsigned char* rgba, int width, int height)
{
  std::fill_n(rgba, width * height * 4, 0xFF);
  const int margin = 20;
  int x = margin, y = margin;

  for(char ch : text)
  {
    if(ch == '\n')
    {
      x = margin;
      y += 9; // 8 pixels + 1 line spacing
      continue;
    }

    // Clamp to valid range
    if(ch < 32 || ch > 126)
      ch = 32;

    // Get font data for this character
    const unsigned char* glyph = &vga_font[(ch - 32) * 8];

    // Draw the character
    for(int row = 0; row < 8; row++)
    {
      for(int col = 0; col < 8; col++)
      {
        if(glyph[row] & (0x80 >> col))
        {
          int px = x + col;
          int py = y + row;

          if(px < width && py < height)
          {
            int offset = (py * width + px) * 4;
            rgba[offset + 0] = 20;  // R
            rgba[offset + 1] = 20;  // G
            rgba[offset + 2] = 20;  // B
            rgba[offset + 3] = 255; // A
          }
        }
      }
    }

    x += 8; // Move to next character position

    // Wrap to next line if needed
    if(x + 8 > width - margin)
    {
      x = margin;
      y += 9;

      // Stop rendering if we've gone past bottom margin
      if(y + 8 > height - margin)
      {
        break;
      }
    }
  }
}
